package com.xd.mocklocation;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.xd.mocklocation.R;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by zhdi7 on 2016/5/13.
 */
public class SystemLocationFragment extends Fragment
        implements ActivityCompat.OnRequestPermissionsResultCallback {

    /**
     * 请求位置许可的ID
     */
    private static final int REQUEST_LOCATION = 1;

    /**
     * 位置许可
     */
    private static String[] PERMISSIONS_LOCATION = {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
    };

    /**
     * 位置管理器
     */
    private LocationManager locationManager = null;

    private LinearLayout layoutLocation = null;
    private TextView tvProvider = null;
    private TextView tvTime = null;
    private TextView tvLatitude = null;
    private TextView tvLongitude = null;
    private TextView tvAltitude = null;
    private TextView tvBearing = null;
    private TextView tvSpeed = null;
    private TextView tvAccuracy = null;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_system_location, null);

        layoutLocation = (LinearLayout) root.findViewById(R.id.layout_location);
        tvProvider = (TextView) root.findViewById(R.id.tv_provider);
        tvTime = (TextView) root.findViewById(R.id.tv_time);
        tvLatitude = (TextView) root.findViewById(R.id.tv_latitude);
        tvLongitude = (TextView) root.findViewById(R.id.tv_longitude);
        tvAltitude = (TextView) root.findViewById(R.id.tv_altitude);
        tvBearing = (TextView) root.findViewById(R.id.tv_bearing);
        tvSpeed = (TextView) root.findViewById(R.id.tv_speed);
        tvAccuracy = (TextView) root.findViewById(R.id.tv_accuracy);

        locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);

        return root;
    }

    @Override
    public void onResume() {
        super.onResume();

        // 注册位置服务，获取系统位置
        if (checkPermission()) {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
        } else {
            requestLocationPermissions();
        }
    }

    @Override
    public void onPause() {
        if (checkPermission()) {
            locationManager.removeUpdates(locationListener);
        }

        super.onPause();
    }

    /**
     * 检查权限
     * @return
     */
    private boolean checkPermission() {
        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
        return true;
    }

    /**
     * 请求位置权限
     */
    private void requestLocationPermissions() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                Manifest.permission.ACCESS_FINE_LOCATION)
                || ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                Manifest.permission.ACCESS_COARSE_LOCATION)) {
            Snackbar.make(layoutLocation, R.string.app_location_permission_demonstrate_access,
                    Snackbar.LENGTH_INDEFINITE)
                    .setAction(R.string.app_ok, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ActivityCompat.requestPermissions(getActivity(),
                                    PERMISSIONS_LOCATION, REQUEST_LOCATION);
                        }
                    }).show();
        } else {
            ActivityCompat.requestPermissions(getActivity(),
                    PERMISSIONS_LOCATION, REQUEST_LOCATION);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_LOCATION) {
            if (verifyPermissions(grantResults)) {
                Snackbar.make(layoutLocation, R.string.app_location_permission_granted,
                        Snackbar.LENGTH_SHORT).show();

                if (checkPermission()) {
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
                }
            } else {
                Snackbar.make(layoutLocation, R.string.app_location_permission_denied,
                        Snackbar.LENGTH_SHORT).show();
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * 验证请求权限的结果
     * @param grantResults
     * @return
     */
    private boolean verifyPermissions(int[] grantResults) {
        if (grantResults == null || grantResults.length < 1) {
            return false;
        }

        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    /**
     * 位置监听
     */
    private LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(final Location location) {
            try {
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvProvider.setText(location.getProvider());
                        tvTime.setText(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(location.getTime())));
                        tvLatitude.setText(location.getLatitude() + " °");
                        tvLongitude.setText(location.getLongitude() + " °");
                        tvAltitude.setText(location.getAltitude() + " m");
                        tvBearing.setText(location.getBearing() + " °");
                        tvSpeed.setText(location.getSpeed() + " m/s");
                        tvAccuracy.setText(location.getAccuracy() + " m");
                    }
                });
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    };
}
